#include<bits/stdc++.h>
using namespace std;
int T,n,m,L,V;
double v2;
double eqs = 0.0001;
bool debug = false;
int ans1,ans2 = 1<<29;
string zstr;
bool v[100010];
struct car
{
    int d,v,a;
}c[100100];
vector<int> p;
vector<string> ps;
string anstr;
bool flag;
void init()
{
    cin>>n>>m>>L>>V;
    v2 = V * V;
    ans1 = 0;
    ans2 = 1<<29;
    zstr = "";
    p.clear();
    ps.clear();

    for(int i = 0;i < m;i++) v[i] = 0;
    for(int i = 0;i < n;i++)
    {
        cin>>c[i].d>>c[i].v>>c[i].a;
        zstr = zstr+'0';
    }
    int a;
    for(int i = 0;i < m;i++)
    {
        cin>>a;
        p.push_back(a);
    }
    sort(p.begin(),p.end());
    if(debug) for(int i:p) printf("%d ",i);
    for(int i = 0;i < m;i++)
    {
        ps.push_back(zstr);
    }
    anstr = zstr;
    if(debug) cout<<zstr<<endl;

}

void solve()
{
    int d,v,a;
    for(int i = 0;i < n;i++)
    {
        d = c[i].d;
        v = c[i].v;
        a = c[i].a;
        if(a == 0 && v <= V) continue;
        if(a < 0 && v <= V) continue;
        if(a > 0 && v <= V)
        {
            double nd;
            nd = v == V ? d :d + (v2 - v * v)/(2 * a);
            if(debug) printf("%d %d %d\nnd:%lf\n",d,v,a,nd);
            if(nd > L) continue;
            int index = lower_bound(p.begin(),p.end(),nd) - p.begin();
            if(v == V || abs(nd - p[index]) < eqs)index++;
            for(int j = index;j < m;j++) ps[j][i] = '1';
        }
        else if(a < 0)//v > V
        {
            double nd;
            nd = d + (v2 - v * v)/(2 * a);
            if(debug) printf("%d %d %d\nnd:%lf\n",d,v,a,nd);
            int index1 = lower_bound(p.begin(),p.end(),d) - p.begin();
            int index2 = lower_bound(p.begin(),p.end(),nd) - p.begin();
            for(int j = index1;j < index2;j++) ps[j][i] = '1';
        }
        else//a == 0 && v > V || a > 0 && v > V
        {
            int index = lower_bound(p.begin(),p.end(),d) - p.begin();
            for(int j = index;j < m;j++)
            {
                ps[j][i] = '1';
            }
        }
    }
    if(debug)for(auto s : ps) cout<<s<<endl;
}

string cover(string str,string str2)
{
    for(int i = 0;i < n;i++) if(str2[i] -'0') str[i] ='1';
    return str;
}

void dfs(int k,int n,string dfstr)
{
    if(debug) cout<<k<<" dfstr"<<dfstr<<endl;
    if(dfstr == anstr) ans2 = min(ans2,k);
    if(k == n)
    {
        return;
    }
    else
    {
        string rem = dfstr;
        for(int i = 0;i < m;i++)
        {
            string nstr = cover(dfstr,ps[i]);
            if(debug)cout<<nstr<<endl;
            if(nstr != dfstr)
            {
                v[i] = 1;
                dfs(k+1,n,nstr);
                v[i] = 0;
            }
            dfstr = rem;
        }

    }

}

int main()
{
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>T;
    for(int i = 0;i < T;i++)
    {
        init();
        solve();
        for(int j = 0;j < m;j++)
        {
            for(int i = 0;i < n;i++)
            {
                if(ps[j][i] - '0') anstr[i] = '1';
            }
        }
        for(int i = 0;i < n;i++) if(anstr[i]-'0') ans1++;
        dfs(0,m,zstr);
        cout<<ans1<<" "<<(m -ans2)<<endl;
    }
    return 0;
}
